

/**
 * 观察者模式基类
 */


export default class Event {

  constructor() {
    this._cache = {}
    this.addToCache()
  }

  /**
   * 调度中心
   */
  addToCache() { }

  /**
   * 观察者模式 往事件池增加一个函数
   * @param {*} type 
   * @param {*} fn 
   * @param {*} context 
   */
  on(type, fn, context) {
    let event = this.getEvent(type)
    if (event) {
      event.addEventListener(fn, context || this)
    }
  }

  /**
   * 观察者模式 往事件池删除一个函数
   * @param {*} type 
   * @param {*} fn 
   */

  off(type, fn, context) {
    let event = this.getEvent(type)
    if (event) {
      event.removeEventListener(fn, context || this)
    }
  }

  /**
   * 触发事件
   * @param {*} type 
   * @param {*} params 
   */

  emit(type, params) {
    let event = this.getEvent(type)
    if (event) {
      raiseEvent(params)
    }
  }

  /**
   * 获取对应消息队列
   * @param {*} type 
   * @returns 
   */

  getEvent(type) {
    return this._cache[type] || undefined
  }

  /**
   * 获取鼠标对象信息
   * @param {*} position 
   * @returns 
   */

  getMouseInfo(position) {
    let scene = this._viewer.scene
    let target = scene.pick(position)
    let cartesian = undefined
    let surfaceCartesian = undefined
    let wgs84Position = undefined
    let wgs84SurfacePosition = undefined
    if (scene.pickPositionSupported) {
      cartesian = scene.pickPosition(position)
    }
    if (cartesian) {
      let c = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian)
      if (c) {
        wgs84Position = {
          lng: Cesium.Math.toDegrees(c.longitude),
          lat: Cesium.Math.toDegrees(c.latitude),
          alt: c.height
        }
      }
    }
    if (
      scene.mode === Cesium.SceneMode.SCENE3D &&
      !(this._viewer.terrainProvider instanceof Cesium.EllipsoidTerrainProvider)
    ) {
      let ray = scene.camera.getPickRay(position)
      surfaceCartesian = scene.globe.pick(ray, scene)
    } else {
      surfaceCartesian = scene.camera.pickEllipsoid(
        position,
        Cesium.Ellipsoid.WGS84
      )
    }
    if (surfaceCartesian) {
      let c = Cesium.Ellipsoid.WGS84.cartesianToCartographic(surfaceCartesian)
      if (c) {
        wgs84SurfacePosition = {
          lng: Cesium.Math.toDegrees(c.longitude),
          lat: Cesium.Math.toDegrees(c.latitude),
          alt: c.height
        }
      }
    }

    return {
      target: target,
      windowPosition: position,
      position: cartesian,
      wgs84Position: wgs84Position,
      surfacePosition: surfaceCartesian,
      wgs84SurfacePosition: wgs84SurfacePosition
    }
  }
}